/*
 * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "sle_hal_test_entry.h"
#include "sle_loader_hal.h"
#include "sle_connect_hal.h"
#include "sle_hal_errcode.h"

static SleConnectHalCallbacks *g_sleConnectHalUtCbs;
static uint16_t g_connectId = 65535;

void OnSleHalUtChangeConnectStateCallback(uint16_t connectId, const SleDeviceAddress *addr
        , SleConnectState connState, SlePairState pairState, SleDisConnectReason discReason)
{
    SLE_UT_LOG("[SleConnectHalTest][PASSED][OnSleHalUtChangeConnectStateCallback] connectId = %d, connState = %d, pairState = %d, discReason = %d", connectId, connState, pairState, discReason);
    if(connState == SLE_CONNECT_CONNECTED_STATE) {
        g_connectId = connectId;
    }
    return;
}

void OnSleHalUtUpdateConnectParamReqCallback(uint16_t connectId, SleHalErrorCode errCode, const SleConnectParam *connParam)
{
    SLE_UT_LOG("[SleConnectHalTest][PASSED][OnSleHalUtUpdateConnectParamReqCallback] connectId = %d, errCode = %d, connParam = %d", connectId, errCode, connParam);
    return;
}

void OnSleHalUtUpdateConnectParamCompleteCallback(uint16_t connectId, SleHalErrorCode errCode, const SleConnectParam *connParam)
{
    SLE_UT_LOG("[SleConnectHalTest][PASSED][OnSleHalUtUpdateConnectParamCompleteCallback] connectId = %d, errCode = %d, connParam = %d", connectId, errCode, connParam);
    return;
}

void OnSleHalUtAuthCompletedCallback(uint16_t connectId, const SleDeviceAddress *addr, SleHalErrorCode errCode, const SleAuthInfo *authInfo)
{
    SLE_UT_LOG("[SleConnectHalTest][PASSED][OnSleHalUtAuthCompletedCallback] connectId = %d, errCode = %d, authInfo = %d", connectId, errCode, authInfo);
    return;
}

void OnSleHalUtPairCompleteCallback(uint16_t connectId, const SleDeviceAddress *addr, SleHalErrorCode errCode)
{
    SLE_UT_LOG("[SleConnectHalTest][PASSED][OnSleHalUtPairCompleteCallback] connectId = %d, errCode = %d", connectId, errCode);
    return;
}

void OnSleHalUtReadRssiCompleteCallback(uint16_t connectId, int32_t rssi, SleHalErrorCode errCode)
{
    SLE_UT_LOG("[SleConnectHalTest][PASSED][OnSleHalUtReadRssiCompleteCallback] connectId = %d, rssi = %d, errCode = %d", connectId, rssi, errCode);
    return;
}

void InitSleConnectHalTestLevel0(void)
{
    SleHalErrorCode ret = SLE_HAL_ERR_UNKNOWN;
    ret = InitSleConnectHal();
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HAL_SUCCESS, "[SleConnectHalTest][FAILED] InitSleConnectHalTestLevel0 failed(%d)",ret);
    SLE_UT_LOG("[SleConnectHalTest][PASSED] InitSleConnectHalTestLevel0 pass");
}

void DeinitSleConnectHalTestLevel0(void)
{
    SleHalErrorCode ret = SLE_HAL_ERR_UNKNOWN;
    ret = DeinitSleConnectHal();
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HAL_SUCCESS, "[SleConnectHalTest][FAILED] DeinitSleConnectHalTestLevel0 failed(%d)",ret);
    SLE_UT_LOG("[SleConnectHalTest][PASSED] DeinitSleConnectHalTestLevel0 pass");
}

void SleConnectHalRegConnectCallbackTestLevel0(void)
{
    SleHalErrorCode ret = SLE_HAL_ERR_UNKNOWN;
    ret = SleConnectHalRegisterCallbacks(g_sleConnectHalUtCbs);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HAL_SUCCESS, "[SleConnectHalTest][FAILED] SleConnectHalRegConnectCallbackTestLevel0 failed(%d)",ret);
    SLE_UT_LOG("[SleConnectHalTest][PASSED] SleConnectHalRegConnectCallbackTestLevel0 pass");
}

void SleConnectHalConnectTestLevel0(void)
{
    SleHalErrorCode ret = SLE_HAL_ERR_UNKNOWN;
    SleDeviceAddress addr = {
        .addrType = SLE_PUBLIC_ADDRESS_TYPE,
        .addr = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06},
    };
    ret = SleConnectHalConnect(&addr);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HAL_SUCCESS, "[SleConnectHalTest][FAILED] SleConnectHalConnectTestLevel0 failed(%d)",ret);
    SLE_UT_LOG("[SleConnectHalTest][PASSED] SleConnectHalConnectTestLevel0 pass");
}

void SleConnectHalUpdateConnParamTestLevel0(void)
{
    SleHalErrorCode ret = SLE_HAL_ERR_UNKNOWN;
    SleConnectionParamUpdate connParam = {
        .connectId = g_connectId,
        .intervalMin = 0x0006,
        .intervalMax = 0x000A,
        .maxLatency = 0x0000,
        .supervisionTimeout = 0x0004,
    };
    ret = SleConnectHalUpdateConnParam(&connParam);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HAL_SUCCESS, "[SleConnectHalTest][FAILED] SleConnectHalUpdateConnParamTestLevel0 failed(%d)",ret);
    SLE_UT_LOG("[SleConnectHalTest][PASSED] SleConnectHalUpdateConnParamTestLevel0 pass");
}

void SleConnectHalSendPairReqTestLevel0(void)
{
    SleHalErrorCode ret = SLE_HAL_ERR_UNKNOWN;
    SleDeviceAddress addr = {
        .addrType = SLE_PUBLIC_ADDRESS_TYPE,
        .addr = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06},
    };
    ret = SleConnectHalSendPairReq(&addr);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HAL_SUCCESS, "[SleConnectHalTest][FAILED] SleConnectHalSendPairReqTestLevel0 failed(%d)",ret);
    SLE_UT_LOG("[SleConnectHalTest][PASSED] SleConnectHalSendPairReqTestLevel0 pass");
}

void SleConnectHalRemovePairTestLevel0(void)
{
    SleHalErrorCode ret = SLE_HAL_ERR_UNKNOWN;
    SleDeviceAddress addr = {
        .addrType = SLE_PUBLIC_ADDRESS_TYPE,
        .addr = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06},
    };
    ret = SleConnectHalRemovePair(&addr);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HAL_SUCCESS, "[SleConnectHalTest][FAILED] SleConnectHalRemovePairTestLevel0 failed(%d)",ret);
    SLE_UT_LOG("[SleConnectHalTest][PASSED] SleConnectHalRemovePairTestLevel0 pass");
}

void SleConnectHalGetPairStateTestLevel0(void)
{
    SleHalErrorCode ret = SLE_HAL_ERR_UNKNOWN;
    SleDeviceAddress addr = {
        .addrType = SLE_PUBLIC_ADDRESS_TYPE,
        .addr = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06},
    };
    SlePairState pairState = SLE_PAIR_ERROR_STATE;
    ret = SleConnectHalGetPairState(&addr, &pairState);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HAL_SUCCESS, "[SleConnectHalTest][FAILED] SleConnectHalGetPairStateTestLevel0 failed(%d)",ret);
    SLE_UT_LOG("[SleConnectHalTest][PASSED] SleConnectHalGetPairStateTestLevel0 pass");
}

void SleConnectHalReadRemoteRssiTestLevel0(void)
{
    SleHalErrorCode ret = SLE_HAL_ERR_UNKNOWN;
    ret = SleConnectHalReadRemoteRssi(g_connectId);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HAL_SUCCESS, "[SleConnectHalTest][FAILED] SleConnectHalReadRemoteRssiTestLevel0 failed(%d)",ret);
    SLE_UT_LOG("[SleConnectHalTest][PASSED] SleConnectHalReadRemoteRssiTestLevel0 pass");
}

void SleConnectHalDisconnectTestLevel0(void)
{
    SleHalErrorCode ret = SLE_HAL_ERR_UNKNOWN;
    SleDeviceAddress addr = {
        .addrType = SLE_PUBLIC_ADDRESS_TYPE,
        .addr = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06},
    };
    ret = SleConnectHalDisconnect(&addr);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HAL_SUCCESS, "[SleConnectHalTest][FAILED] SleConnectHalDisconnectTestLevel0 failed(%d)",ret);
    SLE_UT_LOG("[SleConnectHalTest][PASSED] SleConnectHalDisconnectTestLevel0 pass");
}

void SleConnectHalTestLevel0(void)
{
    SLE_UT_LOG("___SleConnectHalTestLevel0 start");
    InitSleConnectHalTestLevel0();
    SleConnectHalRegConnectCallbackTestLevel0();
    SleConnectHalConnectTestLevel0();
    sleep(1);
    SleConnectHalUpdateConnParamTestLevel0();
    SleConnectHalSendPairReqTestLevel0();
    SleConnectHalRemovePairTestLevel0();
    SleConnectHalGetPairStateTestLevel0();
    SleConnectHalReadRemoteRssiTestLevel0();
    SleConnectHalDisconnectTestLevel0();
    DeinitSleConnectHalTestLevel0();
    SLE_UT_LOG("___SleConnectHalTestLevel0 end");
}

void InitSleConnectHalTestLevel1(void)
{
    SleHalErrorCode ret = SLE_HAL_ERR_UNKNOWN;
    ret = InitSleConnectHal();
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HAL_SUCCESS, "[SleConnectHalTest][FAILED] InitSleConnectHalTestLevel1 failed(%d)",ret);
    SLE_UT_LOG("[SleConnectHalTest][PASSED] InitSleConnectHalTestLevel1 pass1");
    //测试重复调用
    ret = InitSleConnectHal();
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HAL_SUCCESS, "[SleConnectHalTest][FAILED] InitSleConnectHalTestLevel1 failed(%d)",ret);
    SLE_UT_LOG("[SleConnectHalTest][PASSED] InitSleConnectHalTestLevel1 pass2");
}

void DeinitSleConnectHalTestLevel1(void)
{
    SleHalErrorCode ret = SLE_HAL_ERR_UNKNOWN;
    ret = DeinitSleConnectHal();
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HAL_SUCCESS, "[SleConnectHalTest][FAILED] DeinitSleConnectHalTestLevel1 failed(%d)",ret);
    SLE_UT_LOG("[SleConnectHalTest][PASSED] DeinitSleConnectHalTestLevel1 pass1");
    //测试重复调用
    ret = DeinitSleConnectHal();
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HAL_SUCCESS, "[SleConnectHalTest][FAILED] DeinitSleConnectHalTestLevel1 failed(%d)",ret);
    SLE_UT_LOG("[SleConnectHalTest][PASSED] DeinitSleConnectHalTestLevel1 pass2");
}

void SleConnectHalRegConnectCallbackTestLevel1(void)
{
    //测试入参为NULL
    SleHalErrorCode ret = SLE_HAL_ERR_UNKNOWN;
    ret = SleConnectHalRegisterCallbacks(NULL);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HAL_ERR_INVALID_PARAM, "[SleConnectHalTest][FAILED] SleConnectHalRegConnectCallbackTestLevel1 failed(%d)",ret);
    SLE_UT_LOG("[SleConnectHalTest][PASSED] SleConnectHalRegConnectCallbackTestLevel1 pass1");
    ret = SleConnectHalRegisterCallbacks(g_sleConnectHalUtCbs);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HAL_SUCCESS, "[SleConnectHalTest][FAILED] SleConnectHalRegConnectCallbackTestLevel1 failed(%d)",ret);
    SLE_UT_LOG("[SleConnectHalTest][PASSED] SleConnectHalRegConnectCallbackTestLevel1 pass2");
}

void SleConnectHalConnectTestLevel1(void)
{
    //测试入参为NULL
    SleHalErrorCode ret = SLE_HAL_ERR_UNKNOWN;
    ret = SleConnectHalConnect(NULL);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HAL_ERR_INVALID_PARAM, "[SleConnectHalTest][FAILED] SleConnectHalConnectTestLevel1 failed(%d)",ret);
    SLE_UT_LOG("[SleConnectHalTest][PASSED] SleConnectHalConnectTestLevel1 pass");
    SleConnectHalConnectTestLevel0();
}

void SleConnectHalUpdateConnParamTestLevel1(void)
{
    //测试入参为NULL
    SleHalErrorCode ret = SLE_HAL_ERR_UNKNOWN;
    ret = SleConnectHalUpdateConnParam(NULL);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HAL_ERR_INVALID_PARAM, "[SleConnectHalTest][FAILED] SleConnectHalUpdateConnParamTestLevel1 failed(%d)",ret);
    SLE_UT_LOG("[SleConnectHalTest][PASSED] SleConnectHalUpdateConnParamTestLevel1 pass");
    SleConnectHalUpdateConnParamTestLevel0();
}

void SleConnectHalSendPairReqTestLevel1(void)
{
    //测试入参为NULL
    SleHalErrorCode ret = SLE_HAL_ERR_UNKNOWN;
    ret = SleConnectHalSendPairReq(NULL);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HAL_ERR_INVALID_PARAM, "[SleConnectHalTest][FAILED] SleConnectHalSendPairReqTestLevel1 failed(%d)",ret);
    SLE_UT_LOG("[SleConnectHalTest][PASSED] SleConnectHalSendPairReqTestLevel1 pass");
    SleConnectHalSendPairReqTestLevel0();
}

void SleConnectHalRemovePairTestLevel1(void)
{
    //测试入参为NULL
    SleHalErrorCode ret = SLE_HAL_ERR_UNKNOWN;
    ret = SleConnectHalRemovePair(NULL);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HAL_ERR_INVALID_PARAM, "[SleConnectHalTest][FAILED] SleConnectHalRemovePairTestLevel1 failed(%d)",ret);
    SLE_UT_LOG("[SleConnectHalTest][PASSED] SleConnectHalRemovePairTestLevel1 pass");
    SleConnectHalRemovePairTestLevel0();
}

void SleConnectHalGetPairStateTestLevel1(void)
{
    //测试入参为NULL
    SleHalErrorCode ret = SLE_HAL_ERR_UNKNOWN;
    SleDeviceAddress connDevAddress = {
        .addrType = SLE_PUBLIC_ADDRESS_TYPE,
        .addr = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06},
    };
    SlePairState state = SLE_PAIR_ERROR_STATE;
    ret = SleConnectHalGetPairState(NULL, &state);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HAL_ERR_INVALID_PARAM, "[SleConnectHalTest][FAILED] SleConnectHalGetPairStateTestLevel1 failed(%d)",ret);
    SLE_UT_LOG("[SleConnectHalTest][PASSED] SleConnectHalGetPairStateTestLevel1 pass");
    ret = SleConnectHalGetPairState(&connDevAddress, NULL);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HAL_ERR_INVALID_PARAM, "[SleConnectHalTest][FAILED] SleConnectHalGetPairStateTestLevel1 failed(%d)",ret);
    SLE_UT_LOG("[SleConnectHalTest][PASSED] SleConnectHalGetPairStateTestLevel1 pass");
    ret = SleConnectHalGetPairState(&connDevAddress, &state);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HAL_SUCCESS, "[SleConnectHalTest][FAILED] SleConnectHalGetPairStateTestLevel1 failed(%d)",ret);
    SLE_UT_LOG("[SleConnectHalTest][PASSED] SleConnectHalGetPairStateTestLevel1 pass");
}

void SleConnectHalDisconnectTestLevel1(void)
{
    //测试入参为NULL
    SleHalErrorCode ret = SLE_HAL_ERR_UNKNOWN;
    ret = SleConnectHalDisconnect(NULL);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_HAL_ERR_INVALID_PARAM, "[SleConnectHalTest][FAILED] SleConnectHalDisconnectTestLevel1 failed(%d)",ret);
    SLE_UT_LOG("[SleConnectHalTest][PASSED] SleConnectHalDisconnectTestLevel1 pass");
    SleConnectHalDisconnectTestLevel0();
}

void SleConnectHalTestLevel1(void)
{
    SLE_UT_LOG("___SleConnectHalTestLevel1 start");
    InitSleConnectHalTestLevel1();
    SleConnectHalRegConnectCallbackTestLevel1();
    SleConnectHalConnectTestLevel1();
    sleep(1);
    SleConnectHalUpdateConnParamTestLevel1();
    SleConnectHalSendPairReqTestLevel1();
    SleConnectHalRemovePairTestLevel1();
    SleConnectHalGetPairStateTestLevel1();
    SleConnectHalDisconnectTestLevel1();
    DeinitSleConnectHalTestLevel1();
    SLE_UT_LOG("___SleConnectHalTestLevel1 end");
}

SleHalErrorCode InitSleConnectHalTestEntry(void)
{
    g_sleConnectHalUtCbs = (SleConnectHalCallbacks *)malloc(sizeof(SleConnectHalCallbacks));
    g_sleConnectHalUtCbs->OnConnectHalConnectStateChangeCb = OnSleHalUtChangeConnectStateCallback;
    g_sleConnectHalUtCbs->OnConnectHalConnectParamUpdateReqCb = OnSleHalUtUpdateConnectParamReqCallback;
    g_sleConnectHalUtCbs->OnConnectHalConnectParamUpdateCompleteCb = OnSleHalUtUpdateConnectParamCompleteCallback;
    g_sleConnectHalUtCbs->OnConnectHalAuthCompleteCb = OnSleHalUtAuthCompletedCallback;
    g_sleConnectHalUtCbs->OnConnectHalPairCompleteCb = OnSleHalUtPairCompleteCallback;
    g_sleConnectHalUtCbs->OnConnectHalReadRssiCompleteCb = OnSleHalUtReadRssiCompleteCallback;
    SLE_UT_CHECK_AND_RETURN_RET_LOG(g_sleConnectHalUtCbs != NULL, SLE_HAL_ERR_DRIVER_OR_SYSTEM,"[SleConnectHalTest][FAILED] malloc g_sleConnectHalUtCbs failed");
    return SLE_HAL_SUCCESS;
}

SleHalErrorCode DeinitSleConnectHalTestEntry(void)
{
    if(g_sleConnectHalUtCbs != NULL) {
        free(g_sleConnectHalUtCbs);
        g_sleConnectHalUtCbs = NULL;
    }
    return SLE_HAL_SUCCESS;
}

void SleConnectHalTestEntry(void)
{
    SLE_UT_LOG("__SleConnectHalTestEntry start");
    SleHalErrorCode ret = SLE_HAL_ERR_UNKNOWN;
    ret = InitSleConnectHalTestEntry();
    SLE_UT_CHECK_AND_RETURN(ret == SLE_HAL_SUCCESS);
    SleConnectHalTestLevel0();
    SleConnectHalTestLevel1();
    ret = DeinitSleConnectHalTestEntry();
    SLE_UT_CHECK_AND_RETURN(ret == SLE_HAL_SUCCESS);
    SLE_UT_LOG("__SleConnectHalTestEntry end");
}
